<!--index.vue-->
<script setup lang="ts">
import { onMounted, onUnmounted, ref } from "vue";
import { ElMessageBox } from "element-plus";
import { message } from "@/utils/message";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import {
  deleteDevice,
  Device,
  DeviceProperties,
  DeviceStatus,
  DeviceTypeCategory,
  getDeviceProperties,
  getDeviceTypes,
  listDevices,
  listDeviceStatus
} from "@/api/deviceApi";
import Card from "./components/Card.vue";
import DevicePropertiesDialog from "./components/DevicePropertiesDialog.vue";
import DeviceTypeDialog from "./components/DeviceTypeDialog.vue";
import Search from "@iconify-icons/ep/search";
import AddFill from "@iconify-icons/ri/add-circle-line";
import { getRunningExperiments } from "@/api/LabExperimentApi";

defineOptions({
  name: "ListCard"
});

const svg = `
        <path class="path" d="
          M 30 15
          L 28 17
          M 25.61 25.61
          A 15 15, 0, 0, 1, 15 30
          A 15 15, 0, 1, 1, 27.99 7.5
          L 15 15
        " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
      `;

const pagination = ref({ current: 1, pageSize: 12, total: 0 });
const deviceList = ref<Array<Device>>([]);
const dataLoading = ref(true);
const deviceTypeCategories = ref<Array<DeviceTypeCategory>>([]);
const deviceProperties = ref<DeviceProperties>();

let intervalId = null;

const updateDeviceStatus = async () => {
  const response = await listDeviceStatus();
  if (response.errorCode === 0 && response.data) {
    const statusMap = new Map(
      response.data.map((status: DeviceStatus) => [status.deviceId, status])
    );

    for (const device of deviceList.value) {
      const status = statusMap.get(device.id);
      if (status) {
        device.isSetup =
          status.onlineState === 1 || status.onlineState === 2 ? true : false;
        device.status = status;
      }
    }
  }
};

const fetchData = async () => {
  const [deviceTypesRes, devicePropertiesRes, deviceListRes] =
    await Promise.allSettled([
      getDeviceTypes(),
      getDeviceProperties(),
      listDevices()
    ]);

  if (deviceTypesRes.status !== "rejected") {
    deviceTypeCategories.value = deviceTypesRes.value
      .data as Array<DeviceTypeCategory>;
  }
  if (devicePropertiesRes.status !== "rejected") {
    deviceProperties.value = devicePropertiesRes.value.data as DeviceProperties;
  }

  if (deviceListRes.status !== "rejected") {
    deviceList.value = deviceListRes.value.data;
  }
  pagination.value = {
    ...pagination.value,
    total: deviceList.value ? deviceList.value.length : 0
  };
  dataLoading.value = false;

  // 获取设备状态
  await updateDeviceStatus();

  // 每5秒获取一次设备状态
  intervalId = setInterval(updateDeviceStatus, 10000);
};
const disabled = ref(false);

onMounted(async () => {
  fetchData();
  const res = await getRunningExperiments();
  if (!res.errorCode) {
    if (res.data) {
      disabled.value = true;
    }
    console.log(res);
  } else {
    message(`${res.message}`, { type: "error" });
  }
});

// 确保组件卸载时清除定时器
onUnmounted(() => {
  if (intervalId) {
    clearInterval(intervalId);
  }
});

const formDialogVisible = ref(false);
const deviceTypeSelectorVisible = ref(false);
const formData = ref({});
const searchValue = ref("");

const onPageSizeChange = (size: number) => {
  pagination.value.pageSize = size;
  pagination.value.current = 1;
};
const onCurrentChange = (current: number) => {
  pagination.value.current = current;
};
const handleDeleteItem = async (device: Device) => {
  ElMessageBox.confirm(
    device ? `确认删除后${device.name}的所有设备信息将被清空, 且无法恢复` : "",
    "提示",
    { type: "warning" }
  )
    .then(async () => {
      const res = await deleteDevice({ deviceId: device.id });
      if (res.errorCode === 0) {
        message("删除成功", { type: "success" });
        fetchData(); // 重新获取设备列表
      } else {
        message(res.message, { type: "error" }); // 显示错误消息
      }
    })
    .catch(() => {});
};
const handleAddDevice = () => {
  formData.value = { model: formData.value.model };
  deviceTypeSelectorVisible.value = true;
};
const handleEditDevice = (device: Device) => {
  const editData = { ...device, ...device.property };
  editData.model = device.model.toUpperCase();
  delete editData.property;
  delete editData.status;
  formData.value = editData;
  formDialogVisible.value = true;
};
</script>

<template>
  <div class="main">
    <div class="w-full flex justify-between mb-4">
      <el-input
        style="width: 300px"
        v-model="searchValue"
        placeholder="请输入设备名称"
        clearable
      >
        <template #suffix>
          <el-icon class="el-input__icon">
            <IconifyIconOffline
              v-show="searchValue.length === 0"
              :icon="Search"
            />
          </el-icon>
        </template>
      </el-input>
      <el-button
        :disabled="disabled"
        :icon="useRenderIcon(AddFill)"
        @click="handleAddDevice"
      >
        添加
      </el-button>
    </div>
    <div
      v-loading="dataLoading"
      :element-loading-svg="svg"
      element-loading-svg-view-box="-10, -10, 50, 50"
    >
      <el-empty
        description="暂无数据"
        v-show="
          deviceList
            .slice(
              pagination.pageSize * (pagination.current - 1),
              pagination.pageSize * pagination.current
            )
            .filter(v =>
              v.name.toLowerCase().includes(searchValue.toLowerCase())
            ).length === 0
        "
      />
      <template v-if="pagination.total > 0">
        <el-row :gutter="16">
          <el-col
            v-for="(device, index) in deviceList
              .slice(
                pagination.pageSize * (pagination.current - 1),
                pagination.pageSize * pagination.current
              )
              .filter(v =>
                v.name.toLowerCase().includes(searchValue.toLowerCase())
              )"
            :key="index"
            :xs="24"
            :sm="12"
            :md="8"
            :lg="6"
            :xl="4"
          >
            <Card
              :isRuning="disabled"
              :device="device"
              :device-status="device.status"
              @delete-item="handleDeleteItem"
              @manage-device="handleEditDevice"
            />
          </el-col>
        </el-row>
        <el-pagination
          class="float-right"
          v-model:currentPage="pagination.current"
          :page-size="pagination.pageSize"
          :total="pagination.total"
          :page-sizes="[12, 24, 36]"
          :background="true"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="onPageSizeChange"
          @current-change="onCurrentChange"
        />
      </template>
    </div>
    <DevicePropertiesDialog
      v-model:visible="formDialogVisible"
      :data="formData"
      :device-properties="deviceProperties"
      :device-type-categories="deviceTypeCategories"
      @update:visible="formDialogVisible = $event"
      @device-added="fetchData"
    />
    <DeviceTypeDialog
      v-model:visible="deviceTypeSelectorVisible"
      :data="formData"
      @device-type-change="model => (formDialogVisible = true)"
      :device-type-categories="deviceTypeCategories"
    />
  </div>
</template>
